package com.fzu.ess.sys.shiro.realm;

import com.fzu.ess.common.Const;
import com.fzu.ess.sys.entity.Role;
import com.fzu.ess.sys.entity.User;
import com.fzu.ess.sys.service.UserService;
import com.fzu.ess.sys.shiro.MySimpleByteSource;
import com.fzu.ess.sys.utils.MenuUtils;
import com.fzu.ess.sys.utils.RoleUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

public class UserRealm extends AuthorizingRealm {
    @Autowired
    private UserService userService;

    /**
     * 认证信息
     *
     * @param authenticationToken
     * @return
     * @throws org.apache.shiro.authc.AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {

//        System.out.println("password: " );
        UsernamePasswordToken upToken = (UsernamePasswordToken) authenticationToken;
        String username = upToken.getUsername();
        User user = userService.findByUsername(username);

//        System.out.println("password: " + user.getPassword());

        if(user == null){
            throw new UnknownAccountException();//没找到帐号
        }

        switch(user.getLevel()){
            case Const.USER_LEVEL.LOCKED: throw new LockedAccountException(); //帐号未激活
            case Const.USER_LEVEL.UNAVALIABALE: throw new AccountException("账号被冻结！");
        }

        //交给AuthenticatingRealm 使用 CredentialsMatcher 进行密码匹配，如果觉得人家的不好可以自定义实现
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
                user.getUsername(), //用户名
                user.getPassword().toCharArray(), //密码
//                ByteSource.Util.bytes(user.getUsername() + user.getSalt()),//salt=username+salt
                new MySimpleByteSource(user.getUsername() + user.getSalt()),//salt=username+salt
                getName()  //realm name
        );
        return authenticationInfo;
    }

    /**
     * 授权信息
     *
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        String username = (String) principalCollection.getPrimaryPrincipal();

        User user = userService.findByUsername(username);
        List<Role> roleList = user.getRoleList();

        // 添加角色及权限信息
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        authorizationInfo.setRoles(RoleUtils.getRoleNames(roleList));
        authorizationInfo.setStringPermissions(MenuUtils.getPermissionsNames(RoleUtils.getMenuList(roleList)));
        return authorizationInfo;

    }

    @Override
    public void clearCachedAuthorizationInfo(PrincipalCollection principals) {
        super.clearCachedAuthorizationInfo(principals);
    }

    @Override
    public void clearCachedAuthenticationInfo(PrincipalCollection principals) {
        super.clearCachedAuthenticationInfo(principals);
    }

    @Override
    public void clearCache(PrincipalCollection principals) {
        super.clearCache(principals);
    }

    public void clearAllCachedAuthorizationInfo() {
        getAuthorizationCache().clear();
    }

    public void clearAllCachedAuthenticationInfo() {
        getAuthenticationCache().clear();
    }

    public void clearAllCache() {
        clearAllCachedAuthenticationInfo();
        clearAllCachedAuthorizationInfo();
    }

}
